﻿/*
 * zrandom.cxx
 *
 *  Created on: 2015年4月3日
 *      Author: Fifi Lyu
 */

#include "zpsoe/zalgorithm/zrandom.h"
#include "zpsoe/zalgorithm/zstring.h"
#ifdef PLATFORM_WIN32
    #ifndef INCLUDE_WINDOWS_H_FILE
        #define INCLUDE_WINDOWS_H_FILE
        #include <Windows.h>
    #endif
#else
    #include <sys/time.h>
#endif
#include <cstdlib>

namespace zpsoe {

namespace zalgorithm {

namespace zrandom {
ZPSOE_SHARED_LIB_API int64_t get_random() {
#ifdef PLATFORM_WIN32
    LARGE_INTEGER large_interger_;
    QueryPerformanceCounter(&large_interger_);
    int64_t utime_ = large_interger_.QuadPart;
    return utime_;
#else
    // 来源：linux until 中uuid源代码：gen_uuid.c
    struct timeval tv_;
    int32_t ret_ = 0;

    gettimeofday(&tv_, 0);
    srand(tv_.tv_sec ^ tv_.tv_usec);

    // Crank the random number generator a few times
    gettimeofday(&tv_, 0);

    for (int32_t i = (tv_.tv_sec ^ tv_.tv_usec) & 0x1F; i > 0; i--)
        ret_ = rand();

    return ret_;
#endif
}

ZPSOE_SHARED_LIB_API string gen_random(const size_t &size, char_classification_t cc) {
    string s_;
    size_t size_ = 0;

    do {
        int32_t n_ = get_random() % 126;
        bool ret_ = false;

        switch (cc) {
            case CC_ALNUM:
                ret_ = isalnum(n_);
                break;
            case CC_ALPHA:
                ret_ = isalpha(n_);
                break;
            case CC_DIGIT:
                ret_ = isdigit(n_);
                break;
            case CC_PRINT:
                ret_ = (!isspace(n_) && isprint(n_));
                break;
            default:
                break;
        }

        if (ret_) {
            s_.push_back(n_);
            ++size_;
        }

    } while (size_ < size);

    return s_;
}

} /* namespace zrandom */

} /* namespace zalgorithm */

} /* namespace zpsoe */
